<html>
<script>
// 2018-5-11 7:11PM from Jinan to Chengdu
// jimliu.net/2017/03/31/adventure-of-js-iterators-and-compare-to-observables/
// 使得构造拥有自定义迭代器的集合变得相当容易
/*
可以看到调用Symbol.iterator所得到的iter对象只是负责next()工作，而其不断next所得到的it对象则负责value和done工作。

也就是说，在不借助yield的情况下，要实现Symbol.iterator只需要构造一个满足上述接口的对象就OK了，举个例子
*/

var fakeArray = {
  _values: [1, 2, 3, 4, 5, 6],
  [Symbol.iterator]() {

    var _values = this._values;
    var _index = 0;

    var done = function(){
       return _index >= _values.length;
    };

    var iter = {
      next() {
        console.log("Jerry's own iterator, current index: " + _index);
        var it = {
          value: _values[_index],
          done: done() //_index >= _values.length
        }; // end of temporary variable it
        if (!it.done) {
          _index++;
        }
        return it;
      } // end of next()
    }; // end of iter definition
    return iter;
  } // end of Symbol iterator
}

/*
for (var n of fakeArray) {
  console.log(n)
}
*/

function* gen() {
  yield '1-1'
  yield '1-2'
  yield* fakeArray
  yield '1-3'
}
for (var t of gen()) {
   // console.log(t)
}

// 解糖后手工遍历呢？

var iter = gen();
for (var it = iter.next(); !it.done; it = iter.next()) {
  console.log(it)
}

/*
使用迭代器模式，无外乎是为了能工用for-of语法（或者解糖以后自己不断next()）来遍历集合。我们知道迭代器模式是一种典型的“Pull”模型，迭代过程是不断从集合里把东西拉出来，直到什么都拉不出来了
*/

</script>
</html>